﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head><title>Illuminare Score Editor</title>
<link type="text/css" href="css/smoothness/jquery-ui-1.8.16.custom.css" rel="stylesheet" />	
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script src="js/jquery-ui-1.8.16.custom.min.js"></script>
<!--<script src="psalmtone.js"></script>-->
</head>
<body>
<style>
.body{
  max-width:6.5in;
  margin:auto;
}
.sans{font-family:Verdana,Helvetica,sans-serif}
.lnkBtn{
  margin:0.5em;
  margin-left:0;
}
textarea{
  padding:0px;
}
.tap{
  padding-right:2px;
}
.trans {font-size:15px;}
.txtbox {
  margin:0;
  border-width:1px;
}
#chant-image{
  z-index:10;
  position:fixed;
  top:0;
  left:0;
  right:0;
  bottom:0;
  overflow:auto;
}
#chant-image-iframe{
  position:absolute;
  top:33%;
  left:50%;
}
#overlay {
  position:fixed;
  width:auto;
  top:0;
  bottom:0;
  left:0;
  right:0;
  padding:8px;
  background-color:black;
  z-index:5;
  opacity:0.9;
  fliter:alpha(opacity=90);
}
</style>
<div class='body'>
<img alt="Illuminare Score Editor" src="logo.png" style="max-width:3in;display:block;margin:0.75em 0"/>
<div id="toolbar" class="ui-widget-header ui-corner-all" style="padding:4px 4px;margin-bottom:10px">
  <input type="checkbox" id="cbCrop" /><label for="cbCrop">Crop PDF</label>
  <button id="btnWidth">Width: 5in</button>
  <button id="btnHeight">Height: 11in</button>
</div>
<div id="radioWidth" style="display:none;position:absolute">
  <input type="radio" name="rbWidth" value="4" id="rbWidth4"/><label for="rbWidth4">4 inches</label>
  <input type="radio" name="rbWidth" value="5" id="rbWidth5"/><label for="rbWidth5">5 inches</label>
  <input type="radio" name="rbWidth" value="custom" checked id="rbWidthCustom"/><label for="rbWidthCustom"><input type="text" class='txtbox' size="3" id="txtWidth" value="6"/><label for="txtWidth">inches</label></label>
</div>
<div id="radioHeight" style="display:none;position:absolute">
  <input type="radio" name="rbHeight" value="9" checked id="rbHeight9"/><label for="rbHeight9">9 inches</label>
  <input type="radio" name="rbHeight" value="11" id="rbHeight11"/><label for="rbHeight11">11 inches</label>
  <input type="radio" name="rbHeight" value="custom" id="rbHeightCustom"/><label for="rbHeightCustom"><input type="text" class='txtbox' size="3" id="txtHeight" value=""/><label for="txtWidth">inches</label></label>
</div>
<div class="tap"><textarea id="editor" spellcheck="false" style="height: 130pt; width: 100%;">{&#10;&#10;}</textarea></div>
<div class="lnkBtn sans">
<a href="#" id="lnkDownloadLy" draggable target="_blank">Download .ly</a>
&nbsp;&nbsp;<a href="#" title="&lt;Ctrl>+P" id="lnkLily">Preview</a>
&nbsp;&nbsp;<a href="#" title="&lt;Ctrl>+S" id="lnkSaveLily">Save</a>
&nbsp;&nbsp;<a href="#" title="&lt;Ctrl>+&lt;Shift>+P" id="lnkLilyPDF">Lilypond PDF</a>
</div>
<div id="notifications" class="sans"></div>
</div>
<form id="imageForm" target="image" method="post" action="http://www.illuminarepublications.com/editor/ly.php">
<input type="hidden" id="imgf_ly" name="ly"/>
<input type="hidden" id="imgf_width" name="width"/>
<input type="hidden" id="imgf_height" name="height"/>
<input type="hidden" id="imgf_croppdf" name="croppdf"/>
</form>
<div id="chant-image">
  <iframe name="image" id="chant-image-iframe" frameBorder="0" style='background-color:white'></iframe>
</div>
<form id="pdfForm" target="_blank" method="post" action="http://www.illuminarepublications.com/editor/ly.php">
<input type="hidden" id="pdff_ly" name="ly"/>
<input type="hidden" id="pdff_width" name="width"/>
<input type="hidden" id="pdff_height" name="height"/>
<input type="hidden" id="pdff_croppdf" name="croppdf"/>
<input type="hidden" name="fmt" value="pdf"/>
</form>
<div id="overlay" style="display:none;"></div>
<script>
var selHeight,selWidth;

function callLilyPdf(e){
  var filename = "Untitled";
  var ly = $("#editor").val();
  if(e && typeof(e.preventDefault)=="function"){
    e.preventDefault();
  }
  $("#pdff_ly").val(ly);
  $("#pdfForm").submit();
}

function callLilyImage(e){
  var filename = "Untitled";
  var ly = $("#editor").val();
  if(e && typeof(e.preventDefault)=="function"){
    e.preventDefault();
  }
  $("#imgf_ly").val(ly);
  $("#imageForm").submit();
}

function callLily(e){
  if(e && typeof(e.preventDefault)=="function"){
    e.preventDefault();
  }
  processLy($("#editor").val());
}

function updateLocalHeader(header) {
  localStorage.transcribeHeader=header;
}

function splitLy(ly){
  var result=[];
  var lines=ly.split(/\r?\n/);
  var state=0;
  var current='';
  lines.forEach(function(line){
    switch(state){
      case 0:
        if(line.match(/^%%$/))state=1;
        break;
      case 1:
        if(line.match(/^\s*[-\w]+:[^;]+;\s*$/)){
          state=0;
          result.push(current);
          current='';
        }
        break;
    }
    current += line + '\n';
  });
  if(current.length)result.push(current);
  return result;
}

function concatPs(filenames,dim){
  var filename = "!full";
  var notification = $("<div>Processing "+filename+" (" + dim.w + "x" + dim.h + ")...</div>");
  var fadeNotification=function(){notification.fadeOut();};
  $("#notifications").append(notification);
  $.post("http://www.illuminarepublications.com/editor/ly.php",{filenames:filenames.join(' '),fmt:'none',name:filename,croppdf:"false",width:dim.w,height:dim.h})
  .complete(function(e,result){
    if(result=="success"){
      if(e.getResponseHeader("Content-Type")=="text/plain"){
        notification.append("<span style='color:red;font-weight:700'>ERROR:</span><blockquote>"+e.responseText+"</blockquote>");
      } else {
        notification.append("done!");
        setTimeout(fadeNotification,1000);
        return;
      }
    } else {
      notification.append("<span style='color:red;font-weight:700'>"+result+":</span><blockquote>"+e.responseText+"</blockquote>");
    }
    notification.click(fadeNotification);
  });
}
var queueWhenEmpty = [];
var inQueue = 0;
function whenQueueEmptyRun(fun){
  queueWhenEmpty.push(fun);
}
function processLy(ly,filename){
  splitLy(ly).forEach(function(ly){
    var header = null;//getHeader(ly);
    filename=filename || getLyTitle(ly) || "Untitled";
    var dim = dimensionsFromLy(ly);
    var notification = $("<div>Processing "+filename+" (" + dim.w + "x" + dim.h + ")...</div>");
    var fadeNotification=function(){notification.fadeOut();};
    $("#notifications").append(notification);
    ++inQueue;
    $.post("http://www.illuminarepublications.com/editor/ly.php",{ly:ly,fmt:'none',name:filename,croppdf:$("#cbCrop")[0].checked,width:dim.w,height:dim.h})
    .complete(function(e,result){
      if(result=="success"){
        if(e.getResponseHeader("Content-Type")=="text/plain"){
          notification.append("<span style='color:red;font-weight:700'>ERROR:</span><blockquote>"+e.responseText+"</blockquote>");
          --inQueue;
        } else {
          notification.append("done!");
          setTimeout(fadeNotification,1000);
          --inQueue;
          if(inQueue == 0 && queueWhenEmpty.length > 0) {
            var f;
            while(f = queueWhenEmpty.shift()) {
              if(typeof(f)=="function") f();
            }
          }
          return;
        }
      } else {
        notification.append("<span style='color:red;font-weight:700'>"+result+":</span><blockquote>"+e.responseText+"</blockquote>");
        --inQueue;
      }
      notification.click(fadeNotification);
    });
  });
}

function docKeyDown(e){
  if($("#overlay").css("display")!="none"){
    e.preventDefault();
    hideImage();
  }
  if(e.ctrlKey) {
    if(e.which==83) {//S
      //save
      e.preventDefault();
      callLily();
    } else if(e.which==80){//P
      //Preview
      e.preventDefault();
      if(e.shiftKey){
        callLilyPdf();
      } else {
        callLilyImage();
      }      
    }
  }
}

function widthChanged(o){
  var val;
  if(typeof(o) == 'number' && o == selWidth) {
    val = selWidth;
  } else {
    val = $("#rbWidth4")[0].checked? 4 :
      $("#rbWidth5")[0].checked? 5 :
      parseFloat($("#txtWidth").val()) || 5;
    selWidth=val;
  }
  $("#btnWidth").button("option","label","Width: " + val + "in");
  $("#imgf_width").val(val);
  $("#pdff_width").val(val);
  $("div#chant-preview").css("width",(val*1.3)+"in");
}

function heightChanged(o){
  var val;
  if(typeof(o) == 'number' && o == selHeight) {
    val = selHeight;
  } else {
    val = $("#rbHeight9")[0].checked? 9 :
      $("#rbHeight11")[0].checked? 11 :
      parseFloat($("#txtHeight").val()) || 11;
    selHeight=val;
  }
  $("#btnHeight").button("option","label","Height: " + val + "in");
  $("#imgf_height").val(val);
  $("#pdff_height").val(val);
}

function cropChanged(){
  var checked=$('#cbCrop')[0].checked;
  $("#imgf_croppdf").val(checked);
  $("#pdff_croppdf").val(checked);
  $("#cbCrop").button({icons:checked?{primary: "ui-icon-check"}:{}});
}

function hideImage(){
  $("#overlay,#chant-image").hide();
}

function lightboxImage(){
  $ci=$("#chant-image-iframe");
  $i=$("img",$ci[0].contentDocument);
  $($ci[0].contentDocument&&$ci[0].contentDocument.body).css("margin","2px");
  $($ci[0].contentDocument).click(hideImage);
  var width="7in";
  var height="70%";
  if($ci[0].contentDocument && $i[0]){
    width=$i[0].width+4;
    height=$i[0].height+4;
  }
  //$ci.css("width","10000").css("height","10000");
  $ci.css("height",height)
    .css("width",width)
    .css("margin-top",Math.min($ci.parent().height(),$ci.height())*(-0.33))
    .css("margin-left",Math.min($ci.parent().width(),$ci.width())/(-2));
  $("#chant-image,#overlay").show();
}

var dontHide=[];
function showRadio(){
  positionRadio(this);
  var id=this.id.replace(/^btn/,'#radio');
  $(id).fadeIn(200);
  if(dontHide.indexOf(id)==-1)dontHide.push(id);
}
function hideRadio(){
  var id=this.id.replace(/^btn/,'#radio');
  delete dontHide[dontHide.indexOf(id)];
  setTimeout(function(){
    if(dontHide.indexOf(id)==-1)$(id).fadeOut(200);
  }, 100);
}
function dontAllowHide(){
  var id="#"+this.id;
  if(dontHide.indexOf(id)==-1)dontHide.push(id);
}
function allowHide(){
  var id="#"+this.id;
  delete dontHide[dontHide.indexOf(id)];
  setTimeout(function(){
    if(dontHide.indexOf(id)==-1)$(id).fadeOut(200);
  }, 100);
}

function positionRadio(e){
  var id=e.id.match(/^(?:radio|btn)(.*)$/);
  if(!id)return;
  id=id[1];
  var display=$("#radio"+id).css("display");
  $("#radio"+id).show().position({my:"top",at:"bottom",of:$("#btn"+id),offset:"0 -4"}).css("display",display);
}

function getLyTitle(ly){
  var regexTitle = /title\s*=[^"\(]*(?:\([^\)]*\))?[^"]*"([^"]*)"/;
  //var regexTitle = /title\s*=\s*"([^"]*)"/;
  var match = regexTitle.exec(ly);
  if(match) return match[1]
  else return "Untitled";
}

function editorKeyUp(){
  var text = $(this).val();
  setPaperFromLy(text);
}

function dimensionsFromLy(ly) {
  var height = /paper-height\s+=\s+(\d*(?:\.\d+)?)\\in/.exec(ly);
  var width = /paper-width\s+=\s+(\d*(?:\.\d+)?)\\in/.exec(ly);
  height = height? parseFloat(height[1]) : selHeight;
  width = width? parseFloat(width[1]) : selWidth;
  return {w:width, h:height};
}

function setPaperFromLy(ly){
  var dim = dimensionsFromLy(ly);
  selHeight = dim.h
  selWidth = dim.w;
  widthChanged(selWidth);
  heightChanged(selHeight);
}

$(function() {
  var handleDragOver=function(e){
    e.stopPropagation();
    e.preventDefault();
    return false;
  };
  var handleDrop=function(e){
    e.stopPropagation();
    e.preventDefault();
    var $txtArea = $(this);
    var i;
    oe = e.originalEvent;
    var len = oe.dataTransfer.files.length;
    var allFileNames = [];
    var count = 0;
    var readers = [];
    for(i=0; i < len; ++i){
      var file = oe.dataTransfer.files[i];
      var reader=new FileReader();
      var fileName = (file.fileName||file.name);
      var index = fileName.lastIndexOf('.');
      reader.fileName = (index<0)? fileName : fileName.slice(0,index);
      reader.file = file;
      reader.read = function(){ this.readAsText(this.file); }
      allFileNames.push("'" + reader.fileName.replace(/\'/g,"'\\''") + ".ps'");
      reader.onload=function(e){
        if(len == 1) {
          $txtArea
            .val(e.target.result)
            .keyup();
        }
        processLy(e.target.result, e.target.fileName);
        ++count;
        if(len > 1 && count == len)whenQueueEmptyRun(function(){
          concatPs(allFileNames,dimensionsFromLy(e.target.result));
        });
      };
      readers.push(reader);
    }
    for(i=0; i < len; ++i) {
      readers[i].read();
    }
  };
  $("#cbCrop").button({icons:{primary: "ui-icon-check"}});
  $("#radioWidth,#radioHeight").buttonset();
  $("#btnWidth,#btnHeight").button();
  
  $("#lnkLily").click(callLilyImage);
  $("#lnkLilyPDF").click(callLilyPdf);
  $("#lnkSaveLily").click(callLily);
  $("#txtWidth").keyup(widthChanged);
  $("#txtHeight").keyup(heightChanged);
  $("#cbCrop").change(cropChanged);
  $("#btnWidth,#btnHeight").mouseenter(showRadio).mouseleave(hideRadio);
  $("#radioWidth,#radioHeight").mouseenter(dontAllowHide).mouseleave(allowHide);
  $("input[name=rbWidth]").change(widthChanged);
  $("input[name=rbHeight]").change(heightChanged);
  $("#rbWidthCustom").change(function(){if(this.checked)$("#txtWidth").select();});
  $("#rbHeightCustom").change(function(){if(this.checked)$("#txtHeight").select();});
  widthChanged(); heightChanged(); cropChanged();
  $(document).keydown(docKeyDown);
  //setPdfLinkSelector("#lnkLy");
  //setLyLinkSelector("#lnkDownloadLy");
  $("#editor")
    .bind('dragover', handleDragOver)
    .bind('drop', handleDrop)
    .keyup('keyup', editorKeyUp)
    .focus();
  $("#chant-image").hide().click(hideImage);
  $("#overlay").click(hideImage);
  setTimeout(function(){$("#chant-image-iframe").load(lightboxImage)},1000);
});
</script>
</body>
</html>
